package io.github.talelin.latticy.service;

import com.qcloud.cos.COSClient;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.UUID;

/**
 * 腾讯云OSS上传服务
 * 参考missyou项目的实现
 */
@Service
@Slf4j
public class OSSUploadService {

    @Resource
    private COSClient cosClient;

    @Value("${cos.bucket-name}")
    private String bucketName;

    @Value("${cos.domain}")
    private String domain;

    /**
     * 上传字节数组到腾讯云COS
     * @param data 字节数组
     * @param folder 文件夹路径
     * @param fileName 文件名
     * @param contentType 内容类型
     * @return 文件访问URL
     */
    public String uploadToCOS(byte[] data, String folder, String fileName, String contentType) {
        try {
            if (data == null || data.length == 0) {
                throw new IllegalArgumentException("上传数据不能为空");
            }

            // 检查文件大小（限制为100MB）
            if (data.length > 100 * 1024 * 1024) {
                throw new IllegalArgumentException("文件大小不能超过100MB");
            }

            // 检查文件类型
            if (contentType == null || !isAllowedFileType(contentType)) {
                throw new IllegalArgumentException("不支持的文件类型: " + contentType);
            }

            // 生成唯一文件名
            String fileExtension = getFileExtension(fileName);
            String uniqueFileName = generateUniqueFileName(fileExtension);
            
            // 构建完整的文件路径
            String key = folder + uniqueFileName;

            // 设置文件元数据
            ObjectMetadata metadata = new ObjectMetadata();
            metadata.setContentType(contentType);
            metadata.setContentLength(data.length);
            
            // 对于图片文件，设置缓存控制
            if (contentType.startsWith("image/")) {
                metadata.setHeader("Cache-Control", "public, max-age=31536000");
                metadata.setHeader("Content-Disposition", "inline");
            }

            // 上传文件
            InputStream inputStream = new ByteArrayInputStream(data);
            PutObjectRequest putObjectRequest = new PutObjectRequest(
                    bucketName, 
                    key, 
                    inputStream, 
                    metadata
            );

            cosClient.putObject(putObjectRequest);
            inputStream.close();

            // 返回文件访问URL
            String fileUrl = domain + "/" + key;
            log.info("文件上传成功: {}", fileUrl);
            log.info("文件信息: 名称={}, 大小={}, 类型={}, 路径={}", 
                    fileName, data.length, contentType, key);

            return fileUrl;

        } catch (Exception e) {
            log.error("文件上传失败", e);
            throw new RuntimeException("文件上传失败: " + e.getMessage(), e);
        }
    }

    /**
     * 从URL下载图片并上传到COS
     * @param imageUrl 图片URL
     * @param folder 文件夹路径
     * @param fileName 文件名
     * @return 文件访问URL
     */
    public String uploadImageFromUrl(String imageUrl, String folder, String fileName) {
        try {
            log.info("开始从URL下载图片: {}", imageUrl);
            
            // 从URL下载图片
            URL url = new URL(imageUrl);
            InputStream inputStream = url.openStream();
            
            // 读取所有字节
            byte[] data = readAllBytes(inputStream);
            inputStream.close();
            
            // 根据URL确定内容类型
            String contentType = determineContentType(imageUrl);
            
            log.info("图片下载完成，大小: {} bytes, 类型: {}", data.length, contentType);
            
            // 上传到COS
            return uploadToCOS(data, folder, fileName, contentType);
            
        } catch (IOException e) {
            log.error("从URL下载图片失败: {}", imageUrl, e);
            throw new RuntimeException("下载图片失败: " + e.getMessage(), e);
        }
    }

    /**
     * 上传AI生成的图片
     * @param imageUrl AI生成的图片URL
     * @param productName 商品名称
     * @return 文件访问URL
     */
    public String uploadAIGeneratedImage(String imageUrl, String productName) {
        String folder = "ai-generated/";
        String fileName = "product_" + productName.replaceAll("[^a-zA-Z0-9\\u4e00-\\u9fa5]", "_") + ".jpg";
        return uploadImageFromUrl(imageUrl, folder, fileName);
    }

    /**
     * 上传用户头像
     * @param imageUrl 头像URL
     * @param userId 用户ID
     * @return 文件访问URL
     */
    public String uploadUserAvatar(String imageUrl, Long userId) {
        String folder = "avatars/";
        String fileName = "avatar_" + userId + ".jpg";
        return uploadImageFromUrl(imageUrl, folder, fileName);
    }

    /**
     * 上传横幅图片
     * @param imageUrl 横幅URL
     * @param bannerName 横幅名称
     * @return 文件访问URL
     */
    public String uploadBanner(String imageUrl, String bannerName) {
        String folder = "banners/";
        String fileName = "banner_" + bannerName.replaceAll("[^a-zA-Z0-9\\u4e00-\\u9fa5]", "_") + ".jpg";
        return uploadImageFromUrl(imageUrl, folder, fileName);
    }

    /**
     * 删除文件
     * @param fileUrl 文件URL
     */
    public void deleteFile(String fileUrl) {
        try {
            // 从URL中提取文件key
            String key = extractKeyFromUrl(fileUrl);
            cosClient.deleteObject(bucketName, key);
            log.info("文件删除成功: {}", fileUrl);
        } catch (Exception e) {
            log.error("文件删除失败: {}", fileUrl, e);
            throw new RuntimeException("文件删除失败: " + e.getMessage(), e);
        }
    }

    /**
     * 检查文件类型是否允许
     */
    private boolean isAllowedFileType(String contentType) {
        // 允许的图片类型
        String[] allowedImageTypes = {
                "image/jpeg", "image/jpg", "image/png", "image/gif", "image/webp"
        };

        // 检查是否为允许的图片类型
        for (String type : allowedImageTypes) {
            if (type.equals(contentType)) {
                return true;
            }
        }

        return false;
    }

    /**
     * 获取文件扩展名
     */
    private String getFileExtension(String filename) {
        if (filename == null || filename.lastIndexOf(".") == -1) {
            return ".jpg"; // 默认扩展名
        }
        return filename.substring(filename.lastIndexOf("."));
    }

    /**
     * 生成唯一文件名
     */
    private String generateUniqueFileName(String extension) {
        return UUID.randomUUID().toString().replace("-", "") + extension;
    }

    /**
     * 从URL中提取文件key
     */
    private String extractKeyFromUrl(String fileUrl) {
        if (fileUrl.startsWith(domain)) {
            return fileUrl.substring(domain.length() + 1); // +1 for "/"
        }
        return fileUrl;
    }

    /**
     * 根据URL确定内容类型
     */
    private String determineContentType(String imageUrl) {
        String lowerUrl = imageUrl.toLowerCase();
        if (lowerUrl.contains(".png")) {
            return "image/png";
        } else if (lowerUrl.contains(".gif")) {
            return "image/gif";
        } else if (lowerUrl.contains(".webp")) {
            return "image/webp";
        } else {
            return "image/jpeg"; // 默认类型
        }
    }

    /**
     * 读取InputStream的所有字节（Java 8兼容）
     */
    private byte[] readAllBytes(InputStream inputStream) throws IOException {
        byte[] buffer = new byte[8192];
        java.io.ByteArrayOutputStream outputStream = new java.io.ByteArrayOutputStream();
        int bytesRead;
        while ((bytesRead = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, bytesRead);
        }
        return outputStream.toByteArray();
    }
}
